package com.hwf.springboot;

import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.Map;

public class HwfSpringApplication {
    //springboot的真正启动入口
    public static void run(Class clazz) {
        //创建Spring容器
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(clazz);
        applicationContext.refresh();

        WebServer webServer = getWebServer(applicationContext);
        webServer.start(); //启动web容器
        //startTomcat(applicationContext); //启动tomcat容器
    }

    private static WebServer getWebServer(ApplicationContext applicationContext) {
        //返回webServer接口，那么这个接口究竟是Tomcat还是Jetty呢？其实就是Spring容器中有哪个就拿到哪个
        //如果哪道多个要报错，不能同时启动多种WEB容器
        //WebServer webServer= applicationContext.getBean(WebServer.class);
        Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);
        if(webServers.isEmpty()){
            throw new NullPointerException();
        }
        if(webServers.size()>1){
            throw new IllegalStateException();
        }
        //返回唯一的一个Web容器
        return webServers.values().stream().findFirst().get();
    }

    private static void startTomcat(WebApplicationContext applicationContext) {
        Tomcat tomcat = new Tomcat();
        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");

        Connector connector = new Connector();
        connector.setPort(8081);

        Engine engine = new StandardEngine();
        engine.setDefaultHost("localhost");

        Host host = new StandardHost();
        host.setName("localhost");

        String contextPath = "";
        Context context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());

        host.addChild(context);
        engine.addChild(host);

        service.setContainer(engine);
        service.addConnector(connector);

        //spring mvc核心流程----dispatcherServlet
        tomcat.addServlet(contextPath,"dispatcher",new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*","dispatcher");//拦截所有请求派发至disPatcherServlet

        try {
            tomcat.start();
        }catch (LifecycleException e){
            e.printStackTrace();
        }
    }
}
